查看原文
其他

代码篇 || 基于Matlab、EEGLab和ERPlab的偏侧化差异波成分分析

Salahub,Emrich 流浪心球 2022-04-26
之前推送了一篇手动进行偏侧化差异波成分分析,详情见 基于Matlab、EEGLab和ERPlab的偏侧化差异波(N2pc/Pd/CDA )成分分析方法,现在推出其姊妹篇,如何通过代码进行完整的数据分析。
注:代码根据实际需要进行了适当删减和优化。下面将对代码进行一一注解,以便读者理解,如有疑问,欢迎各位通过留言区一起交流。
01 设置路径
%% --------------------------- Set Paths --------------------------------
% Where to load the raw data from .CNT filerawdatapath = pwd; % Where to save todatapath = pwd;% Current directorycd(pwd);% Add to path and open EEGLABeeglab;
02 对数据处理步骤进行初始化操作
%% --------------------------- Initializing -----------------------------
%'...= 0' means do not perform step, '...= 1' means perform stepIMPORT = 0; %Imports the eeg recodings and re-reference them to the mastoids FILTER = 0; %Filters the dataSEGMENT = 0; %Epochs the dataARTIFACT = 0; %Removes blink and eye movement trialsAVERAGE = 0; %Averaged ERPs for each conditionSPLIT = 0; %Lateralized ERPs
03 设置数据列表
%% --------------------------- Participant IDs --------------------------
subjs = {'111','1112','1113','1114','1115','1116','1118','1119','1120','1121','1123'... '1124','1125','1126','1130','1131','1132','1133','1134','1135','1136'... '1138','1139','1141','1142','1143','1145','1146','1148','1149','1150'... '1151','1152','1153','1154','1155','1156','1157','1158','1160','1161'... '1163','1164','1165','1166','1167','1169','1170'};
04 数据导入(以.cnt格式为例)和离线重参考
%% ----------------------- Import and Re-Reference ----------------------
if IMPORT == 1 for i = 1:length(subjs) %Loop through participants s = num2str(subjs{i}); subjdatapath = strcat (datapath, s);subjdatapath = strcat (subjdatapath, '/'); fprintf('********* importing %s \n', subjs{i}); EEG = pop_loadcnt([rawdatapath, subjs{i} '.CNT'] , 'dataformat', 'auto', 'memmapfile', ''); EEG.setname=[subjs{i} '_raw']; EEG = eeg_checkset( EEG ); EEG = pop_reref( EEG, [65 66] ); %Re-reference to mastoids EEG.setname=[subjs{i} '_rr']; EEG = pop_saveset( EEG, 'filename', [subjs{i} '_rr.set'],'filepath', subjdatapath); EEG = eeg_checkset( EEG ); EEG = pop_delset(EEG, [1]); endend 
04 滤波
%% --------------------------- Filtering --------------------------------
if FILTER == 1 %Highpass 0.1, lowpass 40 (butterworth bandpass filter) for i = 1:length(subjs) %lLoop through participants s = num2str(subjs{i}); subjdatapath = strcat (datapath, s);subjdatapath = strcat (subjdatapath, '/'); fprintf('********* filtering subject %s \n', subjs{i}); EEG = pop_loadset('filename',[subjs{i} '_rr.set'],'filepath',subjdatapath); EEG = eeg_checkset( EEG ); EEG = pop_basicfilter( EEG, 1:69 , 'Boundary', 'boundary', 'Cutoff', [0.1 40], 'Design', 'butter', 'Filter', 'bandpass', 'Order', 2, 'RemoveDC', 'on' ); EEG.setname='_rr_filt'; EEG = eeg_checkset( EEG ); EEG = pop_saveset( EEG, 'filename', [subjs{i} '_rr_filt.set'],'filepath',subjdatapath); EEG = eeg_checkset( EEG ); EEG = pop_delset(EEG, [1]); endend
05 建立Event-List、bin 和分段
%% -------------------- Event list, bin, and epoch ----------------------
if SEGMENT == 1 %Create ERP segements fprintf('******** segmenting \n'); for i = 1:length(subjs) %Loop through participants s = num2str(subjs{i}); subjdatapath = strcat (datapath, s);subjdatapath = strcat (subjdatapath, '/'); EEG = pop_loadset('filename',[subjs{i} '_rr_filt.set'],'filepath',subjdatapath); EEG = eeg_checkset( EEG ); EEG = pop_creabasiceventlist( EEG , 'AlphanumericCleaning', 'on', 'BoundaryNumeric', { -99 }, 'BoundaryString', { 'boundary' }, 'Eventlist', [datapath 'temp.txt']); EEG = eeg_checkset( EEG ); EEG = pop_binlister( EEG , 'BDF', [datapath 'manyCircles_bins_accuracy.txt'], 'ExportEL', [subjdatapath subjs{i} '_EL.txt'], 'IndexEL', 1, 'SendEL2', 'EEG&Text', 'Voutput', 'EEG' ); EEG = eeg_checkset( EEG ); EEG = pop_epochbin( EEG , [-200.0 600.0], [-200, 0]); %Epoch from -200 to 600 ms, baseline from -200 to 0 ms search array onset EEG.setname=[subjs{i} '_rr_filt_bin']; EEG = eeg_checkset( EEG ); EEG = pop_saveset( EEG, 'filename', [subjs{i} '_rr_filt_binaccuracy.set'],'filepath', subjdatapath); EEG = eeg_checkset( EEG ); EEG = pop_delset(EEG, [1]); endend
06 对分段数据进行伪迹检测
%% ------------------------ Artifact Detection --------------------------if ARTIFACT == 1 %Remove blinks, lateral eye movements, and high voltage trials fprintf('******* artifacting \n'); for i = 1:length(subjs) %Loop through participants s = num2str(subjs{i}); subjdatapath = strcat (datapath, s);subjdatapath = strcat (subjdatapath, '/'); EEG = pop_loadset('filename',[subjs{i} '_rr_filt_binaccuracy.set'],'filepath',subjdatapath); EEG = eeg_checkset( EEG ); %adding EOG channels EEG = pop_eegchanoperator( EEG, [datapath 'EOG_chan_list_CNT.txt'] , 'ErrorMsg', 'popup', 'Warning', 'off' ); EEG = eeg_checkset( EEG ); %blinks 80 mv from -200 to 400 ms EEG = pop_artmwppth( EEG , 'Channel', [71 72], 'Flag', 1, 'Threshold', 80, 'Twindow', [-200 400], 'Windowsize', 200, 'Windowstep', 100 ); EEG = eeg_checkset( EEG ); %eye movements 32 mv from -200 to 400 ms EEG = pop_artstep( EEG , 'Channel', 70, 'Flag', 2, 'Threshold', 32, 'Twindow', [-200 400], 'Windowsize', 200, 'Windowstep', 50 ); EEG = eeg_checkset( EEG ); %channel activity greater or less than 100 uV in posterior channels %from -200 to 400 ms EEG = pop_eegthresh(EEG, 1, [20:27 57:64], -100, 100, -0.2, 0.4, 1, 0); EEG = pop_saveset( EEG, 'filename',[subjs{i} '_rr_filt_bin_artaccuracy.set'],'filepath',subjdatapath); EEG = eeg_checkset( EEG ); EEG = pop_delset(EEG, [1]); endend
07 对单个被试进行平均
%% ---------------------------- Averaging -------------------------------
if AVERAGE == 1 %Average across channels fprintf('********* averaging \n'); for i = 1:length(subjs) %Loop through participants s = num2str(subjs{i}); subjdatapath = strcat (datapath, s);subjdatapath = strcat (subjdatapath, '/'); EEG = pop_loadset('filename',[subjs{i} '_rr_filt_bin_artaccuracy.set'],'filepath',subjdatapath); EEG = eeg_checkset( EEG ); ERP = pop_averager( EEG , 'Criterion', 'good', 'DSindex', 1, 'ExcludeBoundary', 'on', 'SEM', 'on' ); ERP = pop_savemyerp(ERP, 'erpname',... [subjs{i} '_ERP'], 'filename', [subjs{i} '_ERPaccuracy.erp'], 'filepath', subjdatapath, 'Warning', 'off'); EEG = pop_delset(EEG, [1]); endend
08 进行差异波计算
%% ---------------------- Difference Waveforms --------------------------
if SPLIT == 1 %Split by left/right trials fprintf('******** riding camels \n'); for i = 1:length(subjs) %Loop through participants s = num2str(subjs{i}); subjdatapath = strcat (datapath, s);subjdatapath = strcat (subjdatapath, '/'); ERP = pop_loaderp('filename',[subjs{i} '_ERPaccuracy.erp'],'filepath',subjdatapath); ERP = eeg_checkset( ERP );
ERP = pop_binoperator( ERP, { 'prepareContraIpsi', 'Lch = [ 20:27 65 71]', 'Rch = [ 57:64 66 72]', 'nbin1 = 0.5*bin3@Rch + 0.5*bin1@Lch label 100TargetCorrect Contra',... 'nbin2 = 0.5*bin3@Lch + 0.5*bin1@Rch label 100TargetCorrect Ipsi', 'nbin3 = 0.5*bin4@Rch + 0.5*bin2@Lch label 100TargetIncorrect Contra',... 'nbin4 = 0.5*bin4@Lch + 0.5*bin2@Rch label 100TargetIncorrect Ipsi', 'nbin5 = 0.5*bin7@Rch + 0.5*bin5@Lch label 100DistractorCorrect Contra',... 'nbin6 = 0.5*bin7@Lch + 0.5*bin5@Rch label 100DistractorCorrect Ipsi',... 'nbin7 = 0.5*bin8@Rch + 0.5*bin6@Lch label 100DistractorIncorrect Contra', 'nbin8 = 0.5*bin8@Lch + 0.5*bin6@Rch label 100DistractorIncorrect Ipsi',... 'nbin9 = 0.5*bin11@Rch + 0.5*bin9@Lch label 0TargetCorrect Contra', 'nbin10 = 0.5*bin11@Lch + 0.5*bin9@Rch label 0TargetCorrect Ipsi',... 'nbin11 = 0.5*bin12@Rch + 0.5*bin10@Lch label 0TargetIncorrect Contra', 'nbin12 = 0.5*bin12@Lch + 0.5*bin10@Rch label 0TargetIncorrect Ipsi',... 'nbin13 = 0.5*bin15@Rch + 0.5*bin13@Lch label 0DistractorCorrect Contra', 'nbin14 = 0.5*bin15@Lch + 0.5*bin13@Rch label 0DistractorCorrect Ipsi',... 'nbin15 = 0.5*bin16@Rch + 0.5*bin14@Lch label 0DistractorIncorrect Contra', 'nbin16 = 0.5*bin16@Lch + 0.5*bin14@Rch label 0DistractorIncorrect Ipsi',... 'nbin17 = 0.5*bin19@Rch + 0.5*bin17@Lch label 50TargetCorrect Contra', 'nbin18 = 0.5*bin19@Lch + 0.5*bin17@Rch label 50TargetCorrect Ipsi',... 'nbin19 = 0.5*bin20@Rch + 0.5*bin18@Lch label 50TargetIncorrect Contra', 'nbin20 = 0.5*bin20@Lch + 0.5*bin18@Rch label 50TargetIncorrect Ipsi',... 'nbin21 = 0.5*bin23@Rch + 0.5*bin21@Lch label 50DistractorCorrect Contra', 'nbin22 = 0.5*bin23@Lch + 0.5*bin21@Rch label 50DistractorCorrect Ipsi',... 'nbin23 = 0.5*bin24@Rch + 0.5*bin22@Lch label 50DistractorIncorrect Contra', 'nbin24 = 0.5*bin24@Lch + 0.5*bin22@Rch label 50DistractorIncorrect Ipsi'});
ERP = pop_binoperator( ERP,{'bin25 = bin1 - bin2 label 100TargetC Contra-Ipsi',... 'bin26 = bin3 - bin4 label 100TargetI Contra-Ipsi', 'bin27 = bin5 - bin6 label 100DistractorC Contra-Ipsi', 'bin28 = bin7 - bin8 label 100DistractorI Contra-Ipsi',... 'bin29 = bin9 - bin10 label 0TargetC Contra-Ipsi', 'bin30 = bin11 - bin12 label 0TargetI Contra-Ipsi',... 'bin31 = bin13 - bin14 label 0DistractorC Contra-Ipsi', 'bin32 = bin15 - bin16 label 0DistractorI Contra-Ipsi', 'bin33 = bin17 - bin18 label 50TargetC Contra-Ipsi',... 'bin34 = bin19 - bin20 label 50TargetI Contra-Ipsi', 'bin35 = bin21 - bin22 label 50DistractorC Contra-Ipsi',... 'bin36 = bin23 - bin24 label 50DistractorI Contra-Ipsi'}); ERP = pop_savemyerp(ERP, 'erpname', [subjs{i} '_ERP_splitaccuracy'], 'filename', [subjs{i} '_ERP_splitaccuracy.erp'], 'filepath', subjdatapath); endend
完整代码可通过链接:https://osf.io/rwqhf/ 或点击文末 “阅读原文” 获取,近期也将推出 ERP数据分析中N2pc/Pd成分置换检验的实现 的姊妹篇《代码篇:ERP数据分析中偏侧化成分置换检验的实现》。

因个人精力有限,难免有不足之处。如有不当或遗漏,欢迎大家留言交流。谢谢!


==流浪心球 精品推荐==
ERP数据分析入门指导课程:
01 ERP基础知识 || 02 常见的ERP成分 || 03 ERP的产生和溯源过程 || 04 ERP的优势 || 05 ERP的核心背景知识 || 06 ERP记录与分析方法 || 07 ERP研究的评估

ERP数据分析高阶进击:
ERP数据质量检测新指标(SME)网络研讨会笔记
SME:ERP数据质量检测的新指标
基于Matlab、EEGLab和ERPlab的偏侧化差异波(N2pc/Pd/CDA )成分分析方法
EEG数据分析时如何对分段数据进行伪迹检测与排除?
ERP数据分析中N2pc/Pd成分置换检验的实现
ERP分析中如何自动删除休息阶段的脑电数据?

EEG/ERP研究中避坑指南:
EEG/ERP研究中如何获得稳定可信的结果或效应
采集最佳质量EEG数据的操作流程(1)
在EEG研究中,如何降低COVID-19的传播风险?
脑电数据分析中如何获取相对干净的数据结果?
EEG神经振荡分析:已公开数据及代码共享
ERP CORE:事件相关电位研究的开放资源
 
科研利器

EEG实验中Matlab并口数据位发送和接收的实现方法

攻克心理学研究中文献查阅的七大难关

心理学实验常用编程软件和学习资源汇总

基于SHINE toolbox的图片标准化教程

EEG/ERP学习资源汇总

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存